package gl.drawer

import org.lwjgl.opengl.GL44C.*

/**
 * [org.lwjgl.opengl.GL14C.glMultiDrawArrays] 就不测试了，与多次调用 [org.lwjgl.opengl.GL11.glDrawArrays] 相同
 */
class DrawArrays: Drawer() {

    var program = 0
    var vertex = 0
    var buffer = 0

    // z=0, w=0
    private val vertices = floatArrayOf(
        -0.90f, -0.90f,
         0.85f, -0.90f,
        -0.90f,  0.85f, // Triangle 1
         0.90f, -0.85f,
         0.90f,  0.90f,
        -0.85f,  0.90f, // Triangle 2
    )

    override fun initialize() {
        val vs = glCreateShader(GL_VERTEX_SHADER)
        glShaderSource(GL_VERTEX_SHADER, daVertexShader)
        glCompileShader(vs)
        val fs = glCreateShader(GL_FRAGMENT_SHADER)
        glShaderSource(GL_FRAGMENT_SHADER, daFragmentShader)
        glCompileShader(fs)
        program = glCreateProgram()
        glAttachShader(program, vs)
        glAttachShader(program, fs)
        glLinkProgram(program)
        glDetachShader(program, vs)
        glDetachShader(program, fs)
        glDeleteShader(vs)
        glDeleteShader(fs)
        glLinkProgram(program)
        glUseProgram(program)

        buffer = glGenBuffers()
        glBindBuffer(GL_ARRAY_BUFFER, buffer)
        glBufferStorage(GL_ARRAY_BUFFER, vertices.size * 4L, 0)
        glBufferSubData(GL_ARRAY_BUFFER, 0, vertices)

        vertex = glGenVertexArrays()
        glBindVertexArray(vertex)
        glEnableVertexAttribArray(0)
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0L)
    }

    override fun resume() {
        super.resume()
        glUseProgram(program)
        glBindBuffer(GL_ARRAY_BUFFER, buffer)
        glBindVertexArray(vertex)
        glEnableVertexAttribArray(0)
    }

    override fun update(): Boolean {
        super.update()
        // GL11.glDrawArrays
        glDrawArrays(GL_TRIANGLES, 0, 6)
        return false
    }

    override fun stop() {
        super.stop()
        glDisableVertexAttribArray(0)
        glBindVertexArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glUseProgram(0)
    }

    override fun terminal() {
        glDeleteVertexArrays(vertex)
        glDeleteBuffers(buffer)
        glDeleteProgram(program)
    }
}

val daVertexShader = """
#version 400 core

layout(location=0) in vec4 vPosition;

void main() {
    gl_Position = vPosition;
}
""".trimIndent()

val daFragmentShader = """
#version 400 core

out vec4 fColor;

void main() {
    fColor = vec4(0.5, 0.4, 0.8, 1.0);
}
""".trimIndent()